package com.winit.deploy.server;

import com.winit.common.util.ObjectToString;
import com.winit.core.server.AndroidServer;
import com.winit.deploy.bean.WinitAndroidInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

/**
 * Created by wangjian on 16/10/17.
 */
public class WinitAndroidServer extends AndroidServer {

    private static Logger logger = LoggerFactory.getLogger(WinitAndroidServer.class);

    private WinitAndroidInfo androidInfo;

    public WinitAndroidServer(String ip, String userName, Integer port, WinitAndroidInfo androidInfo) throws Exception {
        super(ip, userName, port);
        this.androidInfo = androidInfo;
    }

    public WinitAndroidInfo getAndroidInfo() {
        return androidInfo;
    }

    /**
     * 推送结束后,校验临时目录下发布包是否存在
     *
     * @throws Exception
     */
    public void doCheckPackage() throws Exception {

        String zipTempDir = this.androidInfo.getZipTempDir();
        String packageName = this.androidInfo.getPackageName();

        if (StringUtils.isEmpty(zipTempDir)
                || StringUtils.isEmpty(packageName)) {
            logger.error("WinitAndroidServer:校验是否推送成功,参数存在空值." + ObjectToString.getString(this.androidInfo));
            throw new Exception("校验是否推送成功,参数存在空值");
        }

        StringBuffer cmd = new StringBuffer();
        cmd.append("ls ").append(zipTempDir).append(" | grep ^").append(packageName).append(".zip$");
        this.initHandler();
        this.doExec(this.handler, cmd.toString());
        logger.info("WinitAndroidServer:校验是否推送成功,返回:" + this.handler.getMessage());
        if (!this.handler.isSuccess()) {
            logger.error("WinitAndroidServer:校验是否推送成功失败.返回:" + this.handler.getMessage());
            throw new Exception("校验是否推送成功失败." + this.handler.getMessage());
        }
        if (StringUtils.isEmpty(this.handler.getMessage())) {
            logger.error("WinitAndroidServer:校验是否推送成功,终端机推送包不存在.");
            throw new Exception("校验是否推送成功,终端机推送包不存在.");
        }
    }

    /**
     * 备份应用
     * 1.进入工程存放目录
     * 2.判断工程文件夹是否存在  存在继续  不存在退出
     * 3.将原工程打包至备份目录
     */
    public void doBakUp() throws Exception {

        String dirPath = this.androidInfo.getProjectDirPath();
        String dirName = this.androidInfo.getProjectDirName();
        String backUpPath = this.androidInfo.getBackUpPath();
        String backUpDir = this.androidInfo.getBackUpDir();

        if (StringUtils.isEmpty(dirPath)
                || StringUtils.isEmpty(dirName)
                || StringUtils.isEmpty(backUpPath)) {
            logger.error("WinitAndroidServer:备份应用,参数存在空值." + ObjectToString.getString(this.androidInfo));
            throw new Exception("备份应用,参数存在空值");
        }

        StringBuffer cmd = new StringBuffer();
        cmd.append("source /etc/profile && cd ").append(dirPath)
                .append(" && sudo tar -zcf ").append(backUpPath).append(" ").append(dirName);
        this.doExec(cmd.toString());
        //删除旧备份文件
        if (!StringUtils.isEmpty(backUpDir) && !StringUtils.isEmpty(dirName)) {
            cmd = new StringBuffer();
            cmd.append("source /etc/profile && cd ").append(backUpDir).append(" && ls | grep ^").append(dirName).append("- && sudo rm -rf `ls -t ")
                    .append(dirName).append("-* | tail -n+4`");
            this.doExec(cmd.toString());
        }
    }

    /**
     * 拷贝工程
     * 1.进入工程存放目录
     * 2.判断工程文件夹是否存在  存在继续  不存在先创建再继续
     * 3.将war包拷贝至工程文件夹目录下并解压
     * 4.解压后删除war包
     */
    public boolean doInstall(String linuxUser) throws Exception {

        String dirPath = this.androidInfo.getProjectDirPath();
        String dirName = this.androidInfo.getProjectDirName();
        String zipTempDir = this.androidInfo.getZipTempDir();
        String packageName = this.androidInfo.getPackageName();

        if (StringUtils.isEmpty(dirPath)
                || StringUtils.isEmpty(dirName)
                || StringUtils.isEmpty(zipTempDir)
                || StringUtils.isEmpty(packageName)) {
            logger.error("WinitAndroidServer:安装程序,参数存在空值." + ObjectToString.getString(this.androidInfo));
            throw new Exception("安装程序,参数存在空值");
        }
        this.initHandler();
        this.doExec(this.handler, "ls " + dirPath + " | grep ^" + dirName + "$");

        if (!this.handler.isSuccess()) {
            logger.error("WinitAndroidServer:安装程序,查询工程目录是否存在失败.返回:" + this.handler.getMessage());
            throw new Exception("安装程序,查询工程目录是否存在失败." + this.handler.getMessage());
        }
        //目录不存在 先创建
        if (StringUtils.isEmpty(this.handler.getMessage())) {
            this.initHandler();
            this.doExec(this.handler, "source /etc/profile && cd " + dirPath + " && sudo mkdir " + dirName);
            if (!this.handler.isSuccess()) {
                logger.error("WinitAndroidServer:安装程序,创建工程目录失败.返回:" + this.handler.getMessage());
                throw new Exception("安装程序,创建工程目录失败." + this.handler.getMessage());
            }
        }

        StringBuffer cmd = new StringBuffer();
        cmd.append("source /etc/profile && sudo cp ").append(zipTempDir).append("/").append(packageName).append(".zip ")
                .append(dirPath).append("/").append(dirName).append("/ && sudo rm -rf ").append(zipTempDir)
                .append("/").append(packageName).append(".zip && cd ").append(dirPath).append("/").append(dirName)
                .append(" && sudo unzip -q -o ").append(packageName).append(".zip && sudo rm -rf ")
                .append(dirPath).append("/").append(dirName).append("/").append(packageName)
                .append(".zip && sudo chown -R ").append(linuxUser).append(".").append(linuxUser).append(" ")
                .append(dirPath).append("/").append(dirName);

        this.initHandler();
        this.doExec(this.handler, cmd.toString());

        if (!this.handler.isSuccess()) {
            logger.error("WinitAndroidServer:安装程序失败.返回:" + this.handler.getMessage());
            throw new Exception("安装程序失败." + this.handler.getMessage());
        }
        return true;
    }

    /**
     * 回滚
     * 1.删除工程目录下的所有文件
     * 2.将备份的文件解压到工程目录下
     *
     * @throws Exception
     */
    public void doRollBack(String linuxUser) throws Exception {

        String backUpPath = this.androidInfo.getBackUpPath();
        String dirPath = this.androidInfo.getProjectDirPath();
        String dirName = this.androidInfo.getProjectDirName();

        if (StringUtils.isEmpty(backUpPath)
                || StringUtils.isEmpty(dirName)
                || StringUtils.isEmpty(dirPath)) {
            logger.error("WinitAndroidServer:执行回滚,参数存在空值." + ObjectToString.getString(this.androidInfo));
            throw new Exception("执行回滚,参数存在空值");
        }
        //1.判断回滚包是否存在
        this.initHandler();
        this.doExec(this.handler, "ls " + backUpPath);
        if (StringUtils.isEmpty(this.handler.getMessage())
                || this.handler.getMessage().indexOf("No such file or directory") != -1) {
            throw new Exception("执行回滚,备份包不存在." + this.androidInfo.getBackUpPath());
        }

        StringBuffer cmd = new StringBuffer();
        cmd.append("source /etc/profile && sudo -u ").append(linuxUser).append(" tar --overwrite -zxf ").append(this.androidInfo.getBackUpPath()).append(" -C ").append(dirPath).append("/ ");

        this.initHandler();
        this.doExec(this.handler, cmd.toString());

        if (!this.handler.isSuccess()) {
            logger.error("WinitAndroidServer:代码回滚失败.返回:" + this.handler.getMessage());
            throw new Exception("代码回滚失败.返回:" + this.handler.getMessage());
        }
    }
}
